package com.ruoyi.common.utils;

import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.enums.PrefixEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
@SuppressWarnings(value = {"rawtypes"})
public class GenerateCodeUtil {

    @Autowired
    public RedisTemplate redisTemplate;

    /**
     * 计算到当日结束还剩多少秒
     */
    public long countdown() {
        long now = System.currentTimeMillis();
        // 计算当前时间到23:59:59还有多少秒
        long sec = (DateUtil.endOfDay(new Date(now)).getTime() - now) / 1000;
        return sec;
    }

    /**
     * 使用Redis计算编号
     * 入参为前缀字母，自动补充年月日序列号
     */
    public String generateNumber(PrefixEnum prefix) {
        long now = System.currentTimeMillis();
        String yyyyMMdd = new SimpleDateFormat("yyyyMMdd").format(now);
        String key = prefix.value() + yyyyMMdd;

        return generateNumber(key, 4);
    }

    /**
     * 使用Redis计算编号
     * 入参就是前缀，只补充序列号；
     *
     * @param noCount 序列号长度，例如3最大值就是999
     */
    public String generateNumber(String prefix, int noCount) {
        return generateNumber(prefix, noCount, countdown());
    }

    /**
     * 使用Redis计算编号
     * 入参就是前缀，只补充序列号；
     *
     * @param noCount 序列号长度，例如3最大值就是999
     * @param sec     控制失效时长
     */
    public String generateNumber(String prefix, int noCount, long sec) {
        RedisAtomicLong counter = new RedisAtomicLong("generateCodeUtil:" + prefix, redisTemplate.getConnectionFactory());
        // 当日最后一秒失效
        counter.expire(sec, TimeUnit.SECONDS);
        long no = counter.incrementAndGet();

        return prefix + String.format("%0" + noCount + "d", no);
    }

}
